<template>
  <div class="personnelOnDuty" @click="handleContainerClick">
    <div
      ref="dragContainerRef"
      v-for="(rowItem, rowIndex) in dataListCopy"
      :key="rowIndex"
      data-target="dragContainer"
      :data-rowIndex="rowIndex"
      :class="[
        'dragContainer',
        dragenterIndex === rowIndex && isDraging ? 'selecting' : ''
      ]"
      @dragover="
        (e) => {
          onDragover(e, rowIndex)
        }
      "
      @dragenter="
        (e) => {
          onDragenter(e, rowIndex)
        }
      "
      @drop="
        (e) => {
          onDrop(e, rowIndex)
        }
      "
      @dragleave="
        (e) => {
          onDragleave(e, rowIndex)
        }
      "
    >
      <div :class="['dragContainer-inner']">
        <drag-item
          v-for="(columnItem, columnIndex) in rowItem.ganttDetails"
          :key="columnIndex"
          :height="height - 10"
          :width="columnItem.width"
          :x_start="columnItem.x_start"
          :dataMsg="columnItem"
          :order="{
            rowIndex,
            columnIndex: columnIndex
          }"
          @x_start_width_changing="
            (val, type) =>
              on_x_start_width_changing(val, type, rowIndex, columnIndex)
          "
          @x_start_width_change_end="
            (val, type) =>
              on_x_start_width_change_end(val, type, rowIndex, columnIndex)
          "
          @drag_start="on_drag_item_drag_start"
        />
        <!-- 虚拟节点 -->
        <div
          data-target="virtualEle"
          :style="{
            left: virtualEleX_start + 'px',
            width: virtualEle_width + 'px'
          }"
          class="virtual-ele"
          @dragleave.prevent
          v-if="dragenterIndex === rowIndex && isDraging"
        >
          松开至此
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { computed, nextTick, onMounted, provide, ref, watch } from 'vue'
import dayjs from 'dayjs'
import dragItem from './dragItem.vue'

onMounted(() => {
  update_position_by_time()
})

const props = defineProps({
  dataList: {
    type: Array,
    default: () => [
      {
        ganttDetails: [
          {
            id: 1,
            startTime: '2023-11-07 00:00:00',
            endTime: '2023-11-07 3:00:00',
            productCode: '物料1',
            process: '工序1',
            ganttStatus: 'Free'
          },
          {
            id: 2,
            startTime: '2023-11-07 03:00:00',
            endTime: '2023-11-07 8:00:00',
            productCode: '物料1',
            process: '工序1',
            ganttStatus: 'Stable'
          },
          {
            id: 3,
            startTime: '2023-11-07 08:00:00',
            endTime: '2023-11-07 10:00:00',
            productCode: '物料2',
            process: '工序2',
            ganttStatus: 'Inserted'
          }
        ]
      },
      {
        ganttDetails: [
          {
            id: 4,
            startTime: '2023-11-07 03:00:00',
            endTime: '2023-11-07 12:00:00',
            productCode: '物料666',
            process: '工序666',
            ganttStatus: 'Inserted'
          }
        ]
      },
      {},
      {},
      {
        ganttDetails: [
          {
            id: 5,
            startTime: '2023-11-07 00:00:00',
            endTime: '2023-11-07 3:00:00',
            productCode: '物料1',
            process: '工序1',
            ganttStatus: 'Free'
          },
          {
            id: 6,
            startTime: '2023-11-07 08:00:00',
            endTime: '2023-11-07 10:00:00',
            productCode: '物料2',
            process: '工序2',
            ganttStatus: 'Free'
          }
        ]
      }
    ]
  }
})

let dragenterIndex = ref(undefined)
// 记录拖拽的起始位置
let dragenterIndex_start = ref(undefined)
let stepWidth = ref(50)
let height = ref(50)
// let curTime = ref(dayjs(new Date()).format('YYYY-MM-DD'))
let curTime = ref('2023-11-07')
let completeTime = computed(() => {
  return `${curTime.value} 00:00:00`
})
let isContainerClick = ref(false)
provide('isContainerClick', isContainerClick)
// let dataList = ref()

const _width = computed(() => {
  return stepWidth.value * 32 + 'px'
})

const _height = computed(() => {
  return height.value + 'px'
})

watch(
  () => props.dataList,
  (newVal) => {
    nextTick(() => {
      dataListCopy.value = JSON.parse(JSON.stringify(newVal))
      update_position_by_time()
    })
  },
  { immediate: true, deep: true } // 测试数据 滚动时未注册registerScroll
)

let dataListCopy = ref([])
let isDraging = ref(false)
let virtualEleX_start = ref(0)
let virtualEle_width = ref(0)
let dragContainerRef = ref(null)
let dragItemMsg = ref(null)

// -------------------------
const onDragenter = (e, rowIndex) => {
  if (e.target.dataset.rowindex) {
    dragenterIndex.value = parseInt(e.target.dataset.rowindex)
    console.log('进入', dragenterIndex.value)
  }
}

const onDragover = (e, rowIndex) => {
  e.preventDefault()
}

const onDragleave = (e) => {
  if (e.target.dataset.target === 'dragContainer' && !isDraging.value) {
    console.log('离开')
  }
}

const onDrop = (e, index) => {}

// --------------------------

// --------------------------

const on_x_start_width_changing = (itemMsg, type) => {
  dragItemMsg.value = itemMsg
  virtualEleX_start.value = itemMsg.x_start
  virtualEle_width.value = itemMsg.width
  isDraging.value = true
  if (type === 'stretch') {
    // 单独处理延展，延展没有拖动不会有拖动索引
    dragenterIndex.value = itemMsg.rowIndex
  }
}

const on_x_start_width_change_end = (itemMsg, type) => {
  dragItemMsg.value = itemMsg
  // dataListCopy.value[rowIndex][columnIndex].x_start = itemMsg.x_start
  // dataListCopy.value[rowIndex][columnIndex].width = itemMsg.width
  handleData_ending(type)
}

const on_drag_item_drag_start = (order) => {
  dragenterIndex_start.value = order.rowIndex
  dragenterIndex.value = order.rowIndex
}

const handleData_ending = (type) => {
  if (type === 'drag') {
    // 拖动
    dataListCopy.value.forEach((item, index) => {
      if (index === dragenterIndex_start.value) {
        item.ganttDetails = item.ganttDetails.filter(
          (it) => it.id !== dragItemMsg.value.id
        )
      }
    })
    dataListCopy.value[dragenterIndex.value].ganttDetails.push({
      ...dragItemMsg.value,
      rowIndex: dragenterIndex.value
    })
  } else {
    // 伸展
    const { rowIndex, columnIndex, x_start, width } = dragItemMsg.value
    dataListCopy.value[rowIndex].ganttDetails[columnIndex].x_start = x_start
    dataListCopy.value[rowIndex].ganttDetails[columnIndex].width = width
  }
  isDraging.value = false
  dragenterIndex.value = undefined
}
// --------------------------

const handleContainerClick = () => {
  isContainerClick.value = true
  setTimeout(() => {
    isContainerClick.value = false
  }, 200)
}

// 通过时间更新位置信息
const update_position_by_time = () => {
  dataListCopy.value.forEach((item) => {
    item.ganttDetails =
      item.ganttDetails?.map((it) => {
        const { startTime, endTime } = it
        const [x_start, x_end] = timeToPosition(
          completeTime.value,
          startTime,
          endTime
        )
        return {
          ...it,
          x_start,
          x_end,
          width: x_end - x_start || 0
        }
      }) || []
  })
  console.log('处理之后的dataList', dataListCopy.value)
}

// 时间转相对位置
const timeToPosition = (basisTime, startTime, endTime) => {
  // 基准时间转时间戳
  const basis_time = new Date(basisTime).getTime()
  // 开始时间转时间戳
  const start_time = new Date(startTime).getTime()
  // 结束时间转时间戳
  const end_time = new Date(endTime).getTime()
  // 时间戳差值
  const basis_to_start = start_time - basis_time
  const start_to_end = end_time - start_time
  const basis_to_end = end_time - basis_time
  // 一天时间戳
  let totalTime = (24 + 8) * 60 * 60 * 1000
  // 容器总长
  let totalWidth = stepWidth.value * (24 + 8)
  // 相对位置
  let position_basis_to_start = (basis_to_start / totalTime) * totalWidth
  let position_basis_to_end = (basis_to_end / totalTime) * totalWidth
  let position_start_to_end = (start_to_end / totalTime) * totalWidth
  return [position_basis_to_start, position_basis_to_end, position_start_to_end]
}
</script>

<style lang="scss" scoped>
.personnelOnDuty {
  width: 100%;
  height: 100%;
  .dragContainer {
    width: v-bind(_width);
    height: v-bind(_height);
    overflow-y: auto;
    padding: 5px 0;
    box-sizing: border-box;
    .dragContainer-inner {
      position: relative;
      width: 100%;
      height: 100%;
      background-color: #f0f0f0;
      box-sizing: border-box;
      .virtual-ele {
        position: absolute;
        z-index: 1;
        top: 0;
        background-color: #fff;
        height: 100%;
        box-sizing: border-box;
        border: 2px dashed red;
        display: flex;
        align-items: center;
        justify-content: center;
        overflow: hidden;
      }
    }
  }
  .selecting {
    border: 1px solid #1890ff;
    box-shadow: 0 0 5px #1890ff;
  }
}
</style>
